#include <bits/stdc++.h>

#define ll long long
#define ull unsigned long long
#define uint unsigned int

#define YES cout << "YES" << '\n'
#define NO cout << "NO" << '\n'
#define endl '\n'
const int INF = 1e9;
const int MOD = 998244353;
using namespace std;

/*思考

*/
const int MAXN = 100005;
int parent[MAXN], sz[MAXN];

// 查找（带路径压缩）
int find_set(int x) {
    if (parent[x] == x) return x;
    return parent[x] = find_set(parent[x]);
}

// 合并（按大小/按秩合并）
void union_set(int x, int y) {
    x = find_set(x);
    y = find_set(y);
    if (x != y) {
        if (sz[x] < sz[y]) swap(x, y);  // 保证x是大集合
        parent[y] = x;
        sz[x] += sz[y];
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, M;
    cin >> N >> M;

    // 初始化
    for (int i = 1; i <= N; i++) {
        parent[i] = i;
        sz[i] = 1;
    }

    // 合并操作
    for (int i = 1; i <= M; i++) {
        int p, q;
        cin >> p >> q;
        union_set(p, q);
    }

    // 统计连通块数量：只统计根节点
    int cnt = 0;
    for (int i = 1; i <= N; i++) {
        if (find_set(i) == i) {  // i是一个集合的代表
            cnt++;
        }
    }

    cout << cnt << '\n';
    return 0;
}